home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ccdl151s.zip / SOURCE / INTEXPR.C < prev    next >
C/C++ Source or Header  |  1997-05-27  |  7KB  |  352 lines

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. /*
  23.  * Evaluate an expression which should be known at compile time.
  24.  * This uses recursive descent.  It is roughly analogous to the
  25.  * primary expression handler except it returns a value rather than
  26.  * an enode list
  27.  */
  28. #include        <stdio.h>
  29. #include        "expr.h"
  30. #include        "c.h"
  31. #include                "errors.h"
  32.  
  33. extern enum e_sym lastst;
  34. extern char lastid[];
  35. extern long ival;
  36. extern TABLE defsyms;
  37. extern TYP stdint, stdchar,stduns, stdunsigned, stdlong, *head;
  38. extern int prm_cmangle;
  39. static long ieprimary(TYP **tp)   
  40. /*
  41.  * PRimary integer
  42.  *    defined(MACRO)
  43.  *    id
  44.  *    iconst
  45.  *    (cast )intexpr
  46.  *    (intexpr)
  47.  */
  48. {       long     temp=0;
  49.         SYM     *sp;
  50.                 if (tp)
  51.                     *tp = &stdint;
  52.         if(lastst == id) {
  53.                     char *lid = lastid;
  54.                     if (prm_cmangle)
  55.                         lid++;
  56.                     sp = gsearch(lastid);
  57.                     if(sp == NULL) {
  58.                                                 gensymerror(ERR_UNDEFINED,lastid);
  59.                         getsym();
  60.                         return 0;
  61.                         }
  62.                     if(sp->storage_class != sc_const && sp->tp->type != bt_enum) {
  63.                         generror(ERR_NEEDCONST,0,0);
  64.                         getsym();
  65.                         return 0;
  66.                         }
  67.                     getsym();
  68.                     return sp->value.i;
  69.         }
  70.         else if(lastst == iconst) {
  71.                 temp = ival;
  72.                 getsym();
  73.                 return temp;
  74.                 }
  75.         else if(lastst == lconst) {
  76.                                 if (tp)
  77.                                     *tp = &stdlong;
  78.                 temp = ival;
  79.                 getsym();
  80.                 return temp;
  81.                 }
  82.         else if(lastst == iuconst) {
  83.                                 if (tp)
  84.                                     *tp = &stduns;
  85.                 temp = ival;
  86.                 getsym();
  87.                 return temp;
  88.                 }
  89.         else if(lastst == luconst) {
  90.                                 if (tp)
  91.                                     *tp = &stdunsigned;
  92.                 temp = ival;
  93.                 getsym();
  94.                 return temp;
  95.                 }
  96.         else if(lastst == cconst) {
  97.                                 if (tp)
  98.                                     *tp = &stdchar;
  99.                 temp = ival;
  100.                 getsym();
  101.                 return temp;
  102.                 }
  103.                 else if (lastst == openpa) {
  104.                     getsym();
  105.                     if (castbegin(lastst)) {
  106.                         decl(0);
  107.                         decl1();
  108.                         needpunc(closepa,0);
  109.                         if (tp)
  110.                           *tp = head;
  111.                         return intexpr(0);
  112.                     }
  113.                     else {
  114.                       temp = intexpr(tp);
  115.                         return(temp);
  116.                     }
  117.                 }
  118.         getsym();
  119.         generror(ERR_NEEDCONST,0,0);
  120.         return 0;
  121. }
  122. /*
  123.  * Integer unary
  124.  *   - unary
  125.  *   ! unary
  126.  *   ~unary
  127.  *   primary
  128.  */
  129. static long ieunary(TYP **tp)
  130. {
  131.     long temp;
  132.     switch (lastst) {
  133.         case minus:
  134.                 getsym();
  135.                 temp = -ieunary(tp);
  136.                 break;
  137.         case not:
  138.                 getsym();
  139.                 temp = !ieunary(tp);
  140.                 break;
  141.         case compl:
  142.                 getsym();
  143.                 temp = ~ieunary(tp);
  144.                 break;
  145.         default:
  146.                 temp = ieprimary(tp);
  147.                 break;
  148.     }
  149.     return(temp);
  150. }
  151. static long iemultops(TYP **tp)
  152. /* Multiply ops */
  153. {
  154.     long val1 = ieunary(tp),val2;
  155.     while (lastst == star || lastst == divide || lastst == modop) {
  156.         TYP *tp1;
  157.         long oper = lastst;
  158.         getsym();
  159.         val2 = ieunary(&tp1);
  160.         switch(oper) {
  161.             case star:
  162.                     val1 = val1 * val2;
  163.                     break;
  164.             case divide:
  165.                     val1 = val1 / val2;
  166.                     break;
  167.             case modop:
  168.                     val1 = val1 % val2;
  169.                     break;
  170.         }
  171.         if (tp)
  172.             *tp = maxsize(*tp,tp1);
  173.     }
  174.     return(val1);
  175. }
  176. static long ieaddops(TYP **tp)
  177. /* Add ops */
  178. {
  179.     long val1 = iemultops(tp),val2;
  180.     while (lastst == plus || lastst == minus)    {
  181.         long oper = lastst;
  182.         TYP *tp1;
  183.         getsym();
  184.         val2 = iemultops(&tp1);
  185.         if (oper == plus) 
  186.             val1 = val1 + val2;
  187.         else
  188.             val1 = val1 - val2;
  189.         if (tp)
  190.             *tp = maxsize(*tp,tp1);
  191.     }
  192.     return(val1);
  193. }
  194. static long ieshiftops(TYP **tp)
  195. /* Shift ops */
  196. {
  197.     long val1 = ieaddops(tp), val2;
  198.     while (lastst == lshift || lastst == rshift) {
  199.         long oper = lastst;
  200.         TYP *tp1;
  201.         getsym();
  202.         val2 = ieaddops(&tp1);
  203.         if (oper == lshift)
  204.             val1 <<= val2;
  205.         else
  206.             val1 >>= val2;
  207.         if (tp)
  208.             *tp = maxsize(*tp,tp1);
  209.     }
  210.     return(val1);
  211. }
  212. static long ierelation(TYP **tp)
  213. /* non-eq relations */
  214. {
  215.     long val1 = ieshiftops(tp), val2;
  216.     while (lastst == lt || lastst == gt || lastst == leq || lastst == geq) {
  217.         long oper = lastst;
  218.         TYP *tp1;
  219.         getsym();
  220.         val2 = ieshiftops(&tp1);
  221.         switch(oper) {
  222.             case lt:
  223.                     val1 = val1 < val2;
  224.                     break;
  225.             case gt:
  226.                     val1 = val1 > val2;
  227.                     break;
  228.             case leq:
  229.                     val1 = val1 <= val2;
  230.                     break;
  231.             case geq:
  232.                     val1 = val1 >= val2;
  233.                     break;
  234.         }
  235.         if (tp)
  236.             *tp = maxsize(*tp,tp1);
  237.     }
  238.     return(val1);
  239. }
  240. static long ieequalops(TYP **tp)
  241. /* eq relations */
  242. {
  243.     long val1 = ierelation(tp),val2;
  244.     while (lastst == eq || lastst == neq) {
  245.         long oper = lastst;
  246.         TYP *tp1;
  247.         getsym();
  248.         val2 = ierelation(&tp1);
  249.         if (oper == neq)
  250.             val1 = val1 != val2;
  251.         else
  252.             val1 = val1 == val2;
  253.         if (tp)
  254.             *tp = maxsize(*tp,tp1);
  255.     }
  256.     return(val1);
  257. }
  258. static long ieandop(TYP **tp)
  259. /* and op */
  260. {
  261.     long val1 = ieequalops(tp),val2;
  262.     while (lastst == and) {
  263.         TYP *tp1;
  264.         getsym();
  265.         val2 = ieequalops(&tp1);
  266.         val1 = val1 & val2;
  267.         if (tp)
  268.             *tp = maxsize(*tp,tp1);
  269.     }
  270.     return(val1);
  271. }
  272. static long iexorop(TYP **tp)
  273. /* xor op */
  274. {
  275.     long val1 = ieandop(tp),val2;
  276.     while (lastst == uparrow) {
  277.         TYP *tp1;
  278.         getsym();
  279.         val2 = ieandop(&tp1);
  280.         val1 = val1 ^ val2;
  281.         if (tp)
  282.             *tp = maxsize(*tp,tp1);
  283.     }         
  284.     return(val1);
  285. }
  286. static long ieorop(TYP **tp)
  287. /* or op */
  288. {
  289.     long val1 = iexorop(tp),val2;
  290.     while (lastst == or) {
  291.         TYP *tp1;
  292.         getsym();
  293.         val2 = iexorop(&tp1);
  294.         val1 = val1 | val2;
  295.         if (tp)
  296.             *tp = maxsize(*tp,tp1);
  297.     }
  298.     return(val1);
  299. }
  300. static long ielandop(TYP **tp)
  301. /* logical and op */
  302. {
  303.     long val1 = ieorop(tp),val2;
  304.     while (lastst == land) {
  305.         TYP *tp1;
  306.         getsym();
  307.         val2 = ieorop(&tp1);
  308.         val1 = val1 && val2;
  309.         if (tp)
  310.             *tp = maxsize(*tp,tp1);
  311.     }
  312.     return(val1);
  313. }
  314. static long ielorop(TYP **tp)
  315. /* logical or op */
  316. {
  317.     long val1 = ielandop(tp),val2;
  318.     while (lastst == lor) {
  319.         TYP *tp1;
  320.         getsym();
  321.         val2 = ielandop(&tp1);
  322.         val1 = val1 || val2;
  323.         if (tp)
  324.             *tp = maxsize(*tp,tp1);
  325.     }
  326.     return(val1);
  327. }
  328. static long iecondop(TYP **tp)
  329. /* Hook op */
  330. {
  331.     long val1 = ielorop(tp),val2, val3;
  332.         if (lastst == hook) {
  333.             TYP *tp1, *tp2;
  334.             getsym();
  335.             val2 = iecondop(&tp1);
  336.             needpunc(colon,0);
  337.             val3 = iecondop(&tp2);
  338.             if (val1)
  339.                 val1 = val2;
  340.             else
  341.                 val1 = val3;
  342.         if (tp)
  343.             *tp = maxsize(tp2,tp1);
  344.         }
  345.     return(val1);
  346. }
  347. long intexpr(TYP **tp)
  348. /* Integer expressions */
  349. {
  350.     return(iecondop(tp));
  351. }
  352.